#include "LED.h"
extern uint8_t BATT_LEDflag;
uint8_t Run_flag = 1;
static u32 Run_buf[][16] = 
{
	{0xFFA500,0,0,0,0xFFA500,0,0,0,0xFFA500,0,0,0,0xFFA500,0,0,0,},//橙色
	{0x00FF00,0,0,0,0x00FF00,0,0,0,0x00FF00,0,0,0,0x00FF00,0,0,0,},//绿色
	{0xFF00FF,0,0,0,0xFF00FF,0,0,0,0xFF00FF,0,0,0,0xFF00FF,0,0,0,},//紫色
	{0x00FFFF,0,0,0,0x00FFFF,0,0,0,0x00FFFF,0,0,0,0x00FFFF,0,0,0,},//青色
	{0x0000FF,0,0,0,0x0000FF,0,0,0,0x0000FF,0,0,0,0x0000FF,0,0,0,},//蓝色
	{0xFFFF00,0,0,0,0xFFFF00,0,0,0,0xFFFF00,0,0,0,0xFFFF00,0,0,0,},//黄色
	{0xFFFFFF,0,0,0,0xFFFFFF,0,0,0,0xFFFFFF,0,0,0,0xFFFFFF,0,0,0,},//白色
};

void LED_Init(void)
{
    //RGB用的端口是PC15,先要失能这个引脚的默认功能和开启引脚复用功能
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO, ENABLE);
    
    RCC_LSEConfig(RCC_LSE_OFF);

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = USER_LED_PIN;
    GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
    GPIO_Init(USER_LED_PORT, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = RGB_LED_PIN;
    GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz;
    GPIO_Init(RGB_LED_PORT, &GPIO_InitStructure);

    USER_LED(1);
	RGB_Pin_H;
	RGB_Reset();
}



void USER_LED_Flash(void)
{
    USER_LED(1);
    delay_ms(100);
    USER_LED(0);
    delay_ms(100);
}


/**
 * @brief 对RGB灯写入0
 *          根据数据手册查得：高电平要求220ns~380ns，低电平延时580ns~1.6us
 * @note 根据计算：1s 进行72M个机器指令 1us 进行了72个机器指令 则每个机器指令花费 13.88ns左右
 *          折中之后：高电平用300ns 低电平用800ns
 *                  300/13.88 = 22     800/13.88 = 57
 */
void RGB_Write0(void)
{   
    RGB_Pin_H;
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
    __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();//20个nop
	RGB_Pin_L;
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();//50个nop
}

/**
 * @brief 对RGB灯写入1
 *          根据数据手册查得：低电平要求220ns~420ns，高电平延时580ns~1.6us
 * @note 根据计算：1s 进行72M个机器指令 1us 进行了72个机器指令 则每个机器指令花费 13.88ns左右
 *          折中之后：高电平用320ns 低电平用1090ns
 *                  800/13.88 = 57    320/13.88=23
 */
void RGB_Write1(void)
{   
	RGB_Pin_H;
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();//50个nop
    RGB_Pin_L;
	__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
    __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();//20个nop
}

/**
 * @brief RGB灯复位
 * @note 复位时序要求是 大于280us以上
 */
void RGB_Reset(void)
{
    RGB_Pin_L;
    delay_us(400);
}

/**
 * @brief 写一个字节（8bit）数据 
 * 
 * @param byte 
 * @note 亮度通过根据更改0x01处的值来进行调节
 */
void RGB_WriteByte(uint8_t byte)
{
    uint8_t i;
    for (i = 0; i < 8; i ++)
    {
        if ((byte >> i) & 0x01) RGB_Write1();
		else RGB_Write0();
    }
}

/**
 * @brief 写入24位数据 设置一个RGB灯的色彩
 * 
 * @param green 
 * @param red 
 * @param blue 
 * @note 灯亮的顺序是 绿 红 蓝，因为一个灯需要写24个数据
 */
void RGB_Write24Bit(uint8_t red, uint8_t green, uint8_t blue)
{
    RGB_WriteByte(green);
    RGB_WriteByte(red);
    RGB_WriteByte(blue);
    // RGB_Reset();
}

void RGB_LED_Red(void)
{
    uint8_t i;
    for (i = 0; i < 4; i ++) RGB_Write24Bit(0xff, 0,0);
}

void RGB_LED_Green(void)
{
	uint8_t i;
	for (i =0; i < 4; i ++) RGB_Write24Bit(0,0xff, 0);
}

void RGB_LED_Blue(void)
{
	uint8_t i;
	for (i = 0; i < 4; i++) RGB_Write24Bit(0 ,0, 0xff);
}

void RGB_LED_Yellow(void)
{
	uint8_t i;
	for (i = 0; i < 4; i ++) RGB_Write24Bit(0xff, 0xff,0);
}

void RGB_LED_Orange(void)
{
	uint8_t i;
	for (i = 0; i < 4; i ++) RGB_Write24Bit(0xff, 0xa5, 0x00);
}

void RGB_LED_Cyan(void)
{
	uint8_t i;
	for (i = 0; i < 4; i ++) RGB_Write24Bit(0, 0xff, 0xff);
}

void RGB_LED_White(void)
{
	uint8_t i;
	for (i = 0; i < 4; i ++) RGB_Write24Bit(0xff, 0xff, 0xff);
}


void RGB_LED_Rand(void)
{
    uint8_t i, red = 0, blue = 0, green = 0;
    for (i = 0; i < 4; i ++)
    {
        green = rand() % 18 + 2;
        red = rand() % 18 + 2;
        blue = rand() % 18 + 2;
        RGB_Write24Bit(green, red, blue);
    }
}

void RGB_LED_OFF(void)
{
	uint8_t i;
	for (i = 0; i < 4; i ++) RGB_Write24Bit(0, 0, 0);
}

void System_Finsh_tip(void)
{
	for (int i = 0; i < 3; i ++)
	{
		RGB_Reset();
		RGB_LED_OFF();	
		delay_ms(200);
		RGB_Reset();
		RGB_LED_White();
		delay_ms(200);
	}
}


//未开锁时低电量检测函数
void BATT_Alarm_LED(void)
{
	static uint8_t flag = 0;
	if (BATT_LEDflag)
	{
		if (flag)
		{
			flag = 0;
			RGB_LED_Red();
		}
		else 
		{
			flag = 1;
			RGB_LED_OFF();
		}
	}
	else RGB_LED_OFF();
}

void LED_Run(void)
{
	static uint8_t flag = 1;
	if (flag)
	{
		flag = 0;
		GPIO_SetBits(USER_LED_PORT, USER_LED_PIN);
	}
	else 
	{
		flag = 1;
		GPIO_ResetBits(USER_LED_PORT, USER_LED_PIN);
	}
}

/**************************************************************************
* 函  数：void RGB_LED_Runing(void)
* 功  能：跑马灯
* 参  数：无
* 返回值：无
* 备  注: 无
**************************************************************************/
void RGB_LED_Runing(void)
{
	uint8_t i,red=0,green=0,blue=0;
	static uint8_t cnt = 0,wcnt = 0,times = 0;
	if(times++ >= 16)
	{
	 times = 0; 
	 wcnt++;
	}
	for(i=0;i<4;i++)
	{
		if(cnt>4) cnt = 0;
		red   = ((Run_buf[wcnt][cnt]>>16)& 0xff);
		green = ((Run_buf[wcnt][cnt]>>8) & 0xff); 
		blue  = ((Run_buf[wcnt][cnt]>>0) & 0xff);
		RGB_Write24Bit(red,green,blue);//合成颜色
		cnt++;
	}
	if(wcnt==7) wcnt = 0;  
}
